package com.stars.easyms.base.util;

import org.apache.commons.codec.binary.Base64;
import org.springframework.lang.Nullable;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * <p>className: AESUtil</p>
 * <p>description: 加密工具类</p>
 *
 * @author guoguifang
 * @version 1.2.2
 * @date 2019/7/25 13:53
 */
public final class AESUtil {

    /**
     * 加密 128位
     *
     * @param content 需要加密的内容
     * @param pkey    秘钥
     * @param iv      秘钥偏移量
     */
    public static byte[] aesEncrypt(String content, String pkey, String iv)
            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException,
            NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
        return getCipher(pkey, iv, true).doFinal(content.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * aes对称加密
     *
     * @param content 待加密字符串
     * @param pkey    长度为16个字符,128位
     * @param iv      秘钥偏移量
     * @return String 返回类型
     */
    public static String aesEncryptStr(String content, String pkey, String iv)
            throws NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException,
            IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
        byte[] aesEncrypt = aesEncrypt(content, pkey, iv);
        return Base64.encodeBase64String(aesEncrypt);
    }

    /**
     * 解密 128位
     *
     * @param content 待解密内容
     * @param pkey    解密密钥
     * @param iv      秘钥偏移量
     */
    public static byte[] aesDecode(byte[] content, String pkey, String iv)
            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException,
            NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
        return getCipher(pkey, iv, false).doFinal(content);
    }

    /**
     * 解密 失败将返回NULL
     *
     * @param content base64处理过的字符串
     * @param pkey    秘钥
     * @param iv      秘钥偏移量
     * @return String 返回类型
     */
    @Nullable
    public static String aesDecodeStr(String content, String pkey, String iv) throws NoSuchPaddingException, InvalidKeyException,
            NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
        byte[] base64DecodeStr = Base64.decodeBase64(content);
        byte[] aesDecode = aesDecode(base64DecodeStr, pkey, iv);
        if (aesDecode == null) {
            return null;
        }
        return new String(aesDecode, StandardCharsets.UTF_8);
    }

    public static Cipher getCipher(String pkey, String iv, boolean isEncrypt)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
        SecretKeySpec key = new SecretKeySpec(pkey.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
        if (isEncrypt) {
            cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
        } else {
            cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
        }
        return cipher;
    }

    private AESUtil() {
    }
}
